A detailed folium example

Author: Leonardo Espin

Date: 11/12/2018

Folium is a python package that allows to create interactive maps.

Below I show an example of how to create a choropleth map with folium. Choropleth maps show areas shaded in proportion to some statistical measurement of interest. In this case I want to show unemployment in the U.S. at the state level.

Let's start with a simple map. By default folium uses OpenStreetMap

In [1]:
import pandas as pd
import folium

#map of NYC
folium_map = folium.Map(location=[37, -102],
                        zoom_start=4,
                        tiles='OpenStreetMap'#this line not strictly necessary
                       )
#show the map
folium_map
Out[1]:

To add the choropleth layer on the map we need two pieces of information:

  • A file that defines the geometric shapes that we want on the map, in the form of a geojson file
  • A file containing the measurement that we want to plot

Folium needs to bind the measurement data with the geometric shapes to be plotted, and so we need to tell folium how to do this.

In [2]:
#Download the file with the shape of the US states from
from urllib.request import urlopen
x = urlopen('https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/search_states.json')
state_geom = x.read().decode("utf-8")#decodingthe bytes object to produce a string

#download the unemployment data from
#https://github.com/python-visualization/folium/tree/master/examples/data
url ="https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/US_Unemployment_Oct2012.csv"
state_data = pd.read_csv(url) 

Let's check the geometry file and the unemployment data frame:

In [3]:
state_data.head()
Out[3]:
State Unemployment
0 AL 7.1
1 AK 6.8
2 AZ 8.1
3 AR 7.2
4 CA 10.1
In [4]:
print(state_geom[0:400])
{"type": "FeatureCollection", "features": [{"type": "Feature", "id": "01", "properties": {"name": "Alabama", "density": 94.65, "color": "#FD8D3C"}, "geometry": {"type": "Polygon", "coordinates": [[[-87.359296, 35.00118], [-85.606675, 34.984749], [-85.431413, 34.124869], [-85.184951, 32.859696], [-85.069935, 32.580372], [-84.960397, 32.421541], [-85.004212, 32.322956], [-84.889196, 32.262709], [-85

It seems that the state polygons are identified with the state name, while in the dataframe states are represented with abreviations.

We need to change abbreviations to names in the dataframe:

In [3]:
#dictionary of state abbreviations can be found here:
#https://gist.github.com/rogerallen/1583593
us_state_abbrev = {
    'Alabama': 'AL',
    'Alaska': 'AK',
    'Arizona': 'AZ',
    'Arkansas': 'AR',
    'California': 'CA',
    'Colorado': 'CO',
    'Connecticut': 'CT',
    'Delaware': 'DE',
    'Florida': 'FL',
    'Georgia': 'GA',
    'Hawaii': 'HI',
    'Idaho': 'ID',
    'Illinois': 'IL',
    'Indiana': 'IN',
    'Iowa': 'IA',
    'Kansas': 'KS',
    'Kentucky': 'KY',
    'Louisiana': 'LA',
    'Maine': 'ME',
    'Maryland': 'MD',
    'Massachusetts': 'MA',
    'Michigan': 'MI',
    'Minnesota': 'MN',
    'Mississippi': 'MS',
    'Missouri': 'MO',
    'Montana': 'MT',
    'Nebraska': 'NE',
    'Nevada': 'NV',
    'New Hampshire': 'NH',
    'New Jersey': 'NJ',
    'New Mexico': 'NM',
    'New York': 'NY',
    'North Carolina': 'NC',
    'North Dakota': 'ND',
    'Ohio': 'OH',
    'Oklahoma': 'OK',
    'Oregon': 'OR',
    'Pennsylvania': 'PA',
    'Rhode Island': 'RI',
    'South Carolina': 'SC',
    'South Dakota': 'SD',
    'Tennessee': 'TN',
    'Texas': 'TX',
    'Utah': 'UT',
    'Vermont': 'VT',
    'Virginia': 'VA',
    'Washington': 'WA',
    'West Virginia': 'WV',
    'Wisconsin': 'WI',
    'Wyoming': 'WY',
}
In [4]:
#we want a dictionary that produces names given abbreviations
inv_abbreviations = {v: k for k, v in us_state_abbrev.items()}

#translate abbreviations into names
state_data['State']=state_data['State'].map(inv_abbreviations)
state_data.head()
Out[4]:
State Unemployment
0 Alabama 7.1
1 Alaska 6.8
2 Arizona 8.1
3 Arkansas 7.2
4 California 10.1

Now we can connect the geometry file with the unemployment data:

In [7]:
# Initialize the map:
example = folium.Map(location=[37, -102], zoom_start=4)
 
# Add the color for the chloropleth:
example.choropleth(
 geo_data=state_geom,
 name='choropleth',
 data=state_data,
 columns=['State', 'Unemployment'],#which columns of the dataframe to use
 key_on='feature.properties.name', #variable shared with the dataframe   
 fill_color='YlGn',
 fill_opacity=0.7,
 line_opacity=0.2,
 legend_name='Unemployment Rate (%)'
)

example #note that the bins for the legend are calculated automatically by folium
Out[7]:

note that the bins for the legend on the top right corner are calculated automatically by folium.

Let's check that the map is correct:

In [5]:
#checking that map is correct:
state_data.sort_values(by=['Unemployment'], ascending=False)
Out[5]:
State Unemployment
27 Nevada 10.3
38 Rhode Island 10.1
4 California 10.1
29 New Jersey 9.6
32 North Carolina 9.4
21 Michigan 9.1
23 Mississippi 9.1
12 Illinois 8.8
39 South Carolina 8.8
9 Georgia 8.8
36 Oregon 8.5
6 Connecticut 8.4
13 Indiana 8.4
31 New York 8.4
8 Florida 8.2
16 Kentucky 8.1
2 Arizona 8.1
37 Pennsylvania 8.0
46 Washington 7.8
41 Tennessee 7.8
5 Colorado 7.7
47 West Virginia 7.5
18 Maine 7.2
3 Arkansas 7.2
7 Delaware 7.1
0 Alabama 7.1
34 Ohio 6.9
1 Alaska 6.8
19 Maryland 6.8
30 New Mexico 6.8
48 Wisconsin 6.8
24 Missouri 6.7
20 Massachusetts 6.7
11 Idaho 6.6
42 Texas 6.4
17 Louisiana 5.9
45 Virginia 5.8
25 Montana 5.8
28 New Hampshire 5.7
22 Minnesota 5.6
15 Kansas 5.6
43 Utah 5.5
10 Hawaii 5.4
35 Oklahoma 5.2
14 Iowa 5.1
49 Wyoming 5.1
44 Vermont 5.0
40 South Dakota 4.4
26 Nebraska 3.9
33 North Dakota 3.2
In [ ]:
# in case we want to save the plot as an html file
example.save('US unemployment 2012.html')